﻿
using CSharpLibs.Annotations;

namespace System.Xml
{
	[Builtin]
	public class XmlWriter : Object, IDisposable
	{
		private System.IO.TextWriter wrs;

		private String[] scopeinfo;
		private int sil;

		public XmlWriter()
		{ 
			this.scopeinfo = new string[20];
			this.sil = 0;
		}

		private static String XmlEncode(String s)
		{
			String res = s;

			res = res.Replace("\"", "&quot;");
			res = res.Replace("&", "&amp;");
			res = res.Replace("'", "&apos;");
			res = res.Replace("<", "&'t;");
			res = res.Replace(">", "&gt;");

			return res;
		}

		public void Close()
		{
			if(this.wrs != null)
			{
				this.wrs.Close();
				this.wrs = null;
			}
		}

		public static XmlWriter Create(System.IO.TextWriter output, XmlWriterSettings settings)
		{
			XmlWriter res = new XmlWriter();
			res.wrs = output;
			return res;
		}

		public void Dispose()
		{ this.Close(); }

		public void Flush()
		{
			if(this.wrs != null)
				this.wrs.Flush();
		}

		public void WriteAttributeString(String localName, String value)
		{
			this.wrs.Write(" ");
			this.wrs.Write(localName);
			this.wrs.Write("=");
			this.wrs.Write("\"" + XmlEncode(value) + "\"");
		}

		public void WriteCData(String text)
		{
			this.wrs.Write("<![CDATA[");
			this.wrs.Write(text);
			this.wrs.Write("]]>");
		}

		public void WriteElementString(String localName, String value)
		{
			this.WriteStartElement(localName);
			this.WriteString(XmlEncode(value));
			this.WriteEndElement();
		}

		public void WriteEndAttribute()
		{ this.wrs.Write("\""); }

		public void WriteEndDocument()
		{ this.wrs.Write("</document>"); }

		public void WriteEndElement()
		{
			String ess = this.scopeinfo[this.sil];
			this.scopeinfo[this.sil] = null;
			this.sil--;
			this.wrs.Write("</" + ess + ">"); 
		}

		public void WriteName(String name)
		{ this.wrs.Write(name); }

		public void WriteStartAttribute(String localName)
		{ this.wrs.Write(localName + "=\""); }

		public void WriteStartDocument()
		{ this.wrs.Write("<document>"); }

		public void WriteStartDocument(bool b)
		{ this.wrs.Write("<document>"); }

		public void WriteStartElement(String localName)
		{
			this.sil++;
			this.scopeinfo[this.sil] = localName;
			this.wrs.Write("<" + localName + ">");
		}

		public void WriteRaw(String value)
		{ this.wrs.Write(value); }

		public void WriteString(String value)
		{ this.wrs.Write(XmlEncode(value)); }

		public void WriteValue(String value)
		{ this.wrs.Write(XmlEncode(value)); }
	}
}
